/**
 *	@file	trcard_sys.c
 *	@brief	トレーナーカードシステム
 *	@author	Miyuki Iwasawa
 *	@date	08.01.16
 */

#include "common.h"
#include "system/procsys.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/buflen.h"
#include "system/palanm.h"
#include "system/savedata.h"
#include "itemtool/itemsym.h"
#include "itemtool/item.h"
#include "gflib/strbuf_family.h"

#include "savedata/config.h"
#include "savedata/record.h"
#include "savedata/trainercard_data.h"

#include "application/mysign.h"
#include "application/trainer_card.h"
#include "trcard_sys.h"

typedef struct _TR_CARD_SYS{
 int heapID;

 void	*app_wk;	///<簡易会話モジュールワークの保存
 PROC*	proc;		///<サブプロセスワーク

 TRCARD_CALL_PARAM* tcp;
 TR_CARD_DATA *pTrCardData;

}TR_CARD_SYS;

//プロトタイプ宣言　ローカル
//================================================================
///オーバーレイプロセス
PROC_RESULT TrCardSysProc_Init( PROC *proc,int *seq);
PROC_RESULT TrCardSysProc_Main( PROC *proc,int *seq);
PROC_RESULT TrCardSysProc_End( PROC *proc,int *seq);

//================================================================
///データ定義エリア
//================================================================
///オーバーレイプロセス定義データ
enum{
 CARD_INIT,
 CARD_WAIT,
 SIGN_INIT,
 SIGN_WAIT,
 CARDSYS_END,
};

static int sub_CardInit(TR_CARD_SYS* wk);
static int sub_CardWait(TR_CARD_SYS* wk);
static int sub_SignInit(TR_CARD_SYS* wk);
static int sub_SignWait(TR_CARD_SYS* wk);

//------------------------------------------------------------------
/**
 * @brief	サブプロセス呼び出し処理
 * @param	proc	サブプロセスポインタを保持するワークへのポインタ
 */
//------------------------------------------------------------------
static BOOL TrCardSysProcCall(PROC ** proc)
{
	if (*proc) {
		if (ProcMain(*proc)) {
			PROC_Delete(*proc);
			*proc = NULL;
			return TRUE;
		}
	}
	return FALSE;
}

/**
 *	@brief	トレーナーカードシステム呼び出し　初期化
 */
PROC_RESULT TrCardSysProc_Init(PROC* proc,int* seq)
{
	TR_CARD_SYS* wk = NULL;
	TRCARD_CALL_PARAM* pp = (TRCARD_CALL_PARAM*)PROC_GetParentWork(proc);

	//ワークエリア取得
	HeapStatePush();

	//ヒープ作成
	sys_CreateHeap(HEAPID_BASE_APP,HEAPID_TRCARD_SYS,0x1000);
	wk = PROC_AllocWork(proc,sizeof(TR_CARD_SYS),HEAPID_TRCARD_SYS);
	MI_CpuClear8(wk,sizeof(TR_CARD_SYS));

	//ヒープID保存
	wk->heapID = HEAPID_TRCARD_SYS;

	//データテンポラリ作成
	wk->tcp = pp;
	wk->pTrCardData = &pp->TrCardData;
	return PROC_RES_FINISH;
}

/**
 *	@brief	トレーナーカード　システムメイン
 */
PROC_RESULT TrCardSysProc_Main(PROC* proc,int* seq)
{
	TR_CARD_SYS* wk = (TR_CARD_SYS*)PROC_GetWork(proc);

	switch(*seq){
	case CARD_INIT:
		*seq = sub_CardInit(wk);
		break;
	case CARD_WAIT:
		*seq = sub_CardWait(wk);
		break;
	case SIGN_INIT:
		*seq = sub_SignInit(wk);
		break;
	case SIGN_WAIT:
		*seq = sub_SignWait(wk);
		break;
	case CARDSYS_END:
	default:
		return PROC_RES_FINISH;
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	トレーナーカード　システム終了
 */
PROC_RESULT TrCardSysProc_End(PROC* proc,int* seq)
{
	TR_CARD_SYS* wk = (TR_CARD_SYS*)PROC_GetWork(proc);

	MI_CpuClear8(wk,sizeof(TR_CARD_SYS));

	//ワークエリア解放
	PROC_FreeWork(proc);

	// 追加SE領域を開放する
	Snd_SubSceneClear( );

	HeapStatePop();
	HeapStateCheck(HEAPID_TRCARD_SYS);

	sys_DeleteHeap(HEAPID_TRCARD_SYS);
	return PROC_RES_FINISH;
}

/**
 *	@brief	トレーナーカード呼び出し
 */
static int sub_CardInit(TR_CARD_SYS* wk)
{
	// オーバーレイID宣言
	FS_EXTERN_OVERLAY(trainer_card);

	// プロセス定義データ
	static const PROC_DATA TrCardProcData = {
		TrCardProc_Init,
		TrCardProc_Main,
		TrCardProc_End,
		FS_OVERLAY_ID(trainer_card),
	};

//	wk->proc = PROC_Create(&TrCardProcData,wk->pTrCardData,wk->heapID);
	wk->proc = PROC_Create(&TrCardProcData,wk->tcp,wk->heapID);
	return CARD_WAIT;
}

/**
 *	@brief	トレーナーカード待ち
 */
static int sub_CardWait(TR_CARD_SYS* wk)
{
	if(!TrCardSysProcCall(&wk->proc)){
		return CARD_WAIT;
	}

	if(wk->tcp->value){
		return SIGN_INIT;
	}
	return CARDSYS_END;
}

/**
 *	@brief	サイン呼び出し
 */
static int sub_SignInit(TR_CARD_SYS* wk)
{
	FS_EXTERN_OVERLAY(mysign);

	// プロセス定義データ
	const PROC_DATA MySignProcData = {
		MySignProc_Init,
		MySignProc_Main,
		MySignProc_End,
		FS_OVERLAY_ID(mysign),
	};

	wk->proc = PROC_Create(&MySignProcData,(void*)wk->tcp->savedata,wk->heapID);
	return SIGN_WAIT;
}

/**
 *	@brief	サイン待ち
 */
static int sub_SignWait(TR_CARD_SYS* wk)
{
	if(!TrCardSysProcCall(&wk->proc)){
		return SIGN_WAIT;
	}
	//サインデータを呼び出しテンポラリに書き戻し
	{
		TR_CARD_SV_PTR trc_ptr = TRCSave_GetSaveDataPtr((SAVEDATA*)wk->tcp->savedata);
		//サインデータの有効/無効フラグを取得(金銀ローカルでのみ有効)
		wk->tcp->TrCardData.MySignValid = TRCSave_GetSigned(trc_ptr);
		//サインデータをセーブデータからコピー
		MI_CpuCopy8(TRCSave_GetSignDataPtr(trc_ptr),
				wk->tcp->TrCardData.SignRawData, SIGN_SIZE_X*SIGN_SIZE_Y*8 );
	}
	return CARD_INIT;
}


